Add OIDC trusted publishing + staged npm releases via GitHub Actions#363
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d runtime Apply the fixes validated on the passport-intercom and cli publish workflows: - verify: use fetch-depth: 0 and drop the manual `git fetch --depth=1`, so the default-branch ancestry check has the history it needs (the double-shallow version could only pass when the tag was the branch tip) - add a top-level concurrency group so overlapping releases serialize instead of racing for a dist-tag - add timeout-minutes: 15 to stage-publish Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
ReviewPorted the RN OIDC staged-publishing workflow (intercom/intercom-react-native#360) faithfully on the security scaffolding — SHA-pinned actions, env-var indirection for the release tag, least-privilege 🔴 Blocker 1 — Workflow runs from repo root, but there is no root
|
…sh, pin SHA between jobs - Run version assert, dist-tag resolve, and `npm stage publish` inside intercom-plugin/ (the publishable package lives there; no root package.json). - Remove the CircleCI token-based publish job and its workflow wiring so releases no longer double-publish / race on the dist-tag. - verify now outputs the ancestry-checked SHA; stage-publish checks out that exact SHA instead of re-resolving the mutable tag (closes the TOCTOU window). - Remove the resolved CAVEAT template header. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@imSzukala Thanks for the review. I've updated per your feedback 🙇♂️ |
imSzukala
left a comment
There was a problem hiding this comment.
Approving — this faithfully mirrors the merged RN reference (intercom-react-native#360) and correctly adapts it to this repo's structure. I verified the structural claims against the tree.
Verified ✅
intercom-plugin/package.jsonhas noscripts→ no build/prepare step needed- No lockfile in
intercom-plugin/, and no rootpackage.json(henceworking-directory: ./intercom-pluginfor the version assert) - Old
circle.ymlpublish job ran onlynpm publish→ behavior preserved, no build regression - No
.npmignore/filesfield → publishes the whole dir, same as before - Tags are plain numeric, so
${RELEASE_TAG#v}is a harmless defensive strip
Parity with #360
Pinned action SHAs, least-privilege permissions (id-token: write only on the publish job), serialized concurrency with cancel-in-progress: false, default-branch ancestry check + SHA pinning (TOCTOU guard), persist-credentials: false, package-manager-cache: false, npm 11.15.0 + npm stage publish --tag, and the prerelease dist-tag guard — all match.
The one intentional divergence — omitting the test job that RN runs — is justified: this package has no JS test suite or build, ships source as-is, and the old CircleCI job did the same.
Minor, non-blocking
- RN runs a version-format regex before the tag-vs-package equality check; here it's equality only. The equality check is the part that matters; the regex is optional defense-in-depth.
- RN pins
ref: ${{ github.event.release.tag_name }}on the validate checkout; here theverifyjob relies on the defaultgithub.sha. Equivalent forreleaseevents — adding the explicitrefwould just match RN. - The human-approval gate is entirely npm-side (
npm stage publishstages; a maintainer promotes on npmjs.com) — same as RN. Worth confirming the npm org has staged publishing + the OIDC trusted-publisher config set up forcordova-plugin-intercombefore the first release run.
|
Thanks @imSzukala. I've enabled the OIDC + staged publishing on the npm side now. |
Why?
Moves npm publishing onto short-lived, per-run OIDC credentials with a human approval step, removing the need for a stored long-lived npm token.
How?
Adds a release-triggered GitHub Actions workflow that authenticates to npm via OIDC (no token) and uses npm's staged publishing, so each release is queued for a maintainer to approve before it goes live.
Generated with Claude Code